// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace svs.Mobile.BeyondMedia.FeedCore.RSS
{
	public class DownloadStatisticsList : List<DownloadStatistics>
	{
		private DateTime? _DownloadTime;

		/// <summary>
		/// Date time download started
		/// </summary>
		public DateTime? DownloadTime
		{
			get { return _DownloadTime; }
			set { _DownloadTime = value; }
		}

		public override string ToString()
		{
			StringBuilder retVal = new StringBuilder();

			if (Count > 0)
				ForEach(delegate(DownloadStatistics stat) { retVal.Append(stat); });
			else
				retVal.Append("There are no Statistics available!");

			return retVal.ToString();
		}

		/// <summary>
		/// Gets a list of all downloads that have completed
		/// </summary>
		/// <returns></returns>
		public List<DownloadStatistics> GetSuccesfulDownloads()
		{
			return FindAll(delegate(DownloadStatistics ds) { return ds != null && ds.CompletedNormaly; });
		}

		/// <summary>
		/// Clear sthe download statistics
		/// </summary>
		public void ClearStatistics()
		{
			Clear();
			DownloadTime = null;
		}
	}

	public class DownloadStatistics
	{
		public bool CompletedNormaly = false;
		public string ContentEncoding;
		public DateTime? ContentLastModifyDate;
		public long? DownloadedSize;
		public bool DownloadSkipped = false;
		public int DownloadTime = -1;
		public DateTime EventDate;
		public bool ImageDownloaded = false;
		public Exception LastException;
		public Feed OwnerFeed;
		public Track OwnerTrack;
		public DateTime? SkipDate;
		public long? SkipSize;
		public long StartPosition;
		public bool Terminated = false;

		public int TimeToFirstByte = -1;
		public long? TotalSize;
		public string Url;

		public string DownloadSpeed
		{
			get
			{
				if (string.IsNullOrEmpty(ContentEncoding) && DownloadTime > 0 && DownloadedSize > 0)
					//for non compressed streams
				{
					double size = Math.Round((double) DownloadedSize/1024);
					return size/DownloadTime + "kb/s.";
				}
				else
				{
					return "<N/A>";
				}
			}
		}

		public override string ToString()
		{
			StringBuilder retVal = new StringBuilder();

			string status;
			string color;

			if (CompletedNormaly)
			{
				status = "Completed";
				color = "DarkGreen";
			}
			else if (Terminated)
			{
				status = "Canceled";
				color = "Goldenrod";
			}
			else if (DownloadSkipped)
			{
				status = "Unchanged";
				color = "DodgerBlue";
			}
			else
			{
				status = "Failed";
				color = "Firebrick";
			}

			retVal.AppendFormat(CultureInfo.CurrentCulture, "<div style='color: {2}'><b>{0}</b> - {1}",
			                    OwnerTrack == null ? (OwnerFeed == null ? "Unknown" : OwnerFeed.Name) : OwnerTrack.Name, status,
			                    color);

			retVal.Append("<ul style='margin-top:5px; margin-bottom:5px'>");

			retVal.AppendFormat(CultureInfo.CurrentCulture, "<li>Url: {0}</li>", Url);

			if (!DownloadSkipped)
			{
				retVal.AppendFormat(CultureInfo.CurrentCulture,
				                    "<li>Downloaded: <b>{0}</b>, starting at position: <b>{1}</b> took: <b>{2}</b> at <b>{3}</b></li>",
				                    DownloadedSize ?? 0, StartPosition,
				                    CoreHelper.GetTimeDurationAsString(DownloadTime + TimeToFirstByte),
				                    CoreHelper.GetDownloadSpeedAsString(DownloadedSize ?? 0, DownloadTime + TimeToFirstByte));
			}

			retVal.AppendFormat(CultureInfo.CurrentCulture,
			                    "<li>Content Size: <b>{0}</b>. Cache Size: <b>{1}</b></li>",
			                    TotalSize ?? 0, SkipSize.HasValue ? SkipSize.ToString() : "Not Set");

			retVal.AppendFormat(CultureInfo.CurrentCulture,
			                    "<li>Content Date: <b>{0}</b>. Cache Date: <b>{1}</b></li>",
			                    ContentLastModifyDate.HasValue ? ContentLastModifyDate.ToString() : "Unknown",
			                    SkipDate.HasValue ? SkipDate.ToString() : "Not Set");

			retVal.AppendFormat(CultureInfo.CurrentCulture,
										"<li>Feed has Image: <b>{0}</b>, image downloaded: <b>{1}</b></li>",
										string.IsNullOrEmpty(OwnerFeed.FeedImageUrl) ? "No" : "Yes",
										FeedImageCache.HasCachedImageFor(OwnerFeed) ? "Yes" : "No");

			if (!DownloadSkipped)
			{
				retVal.AppendFormat(CultureInfo.CurrentCulture,
				                    "<li>Content Compression: <b>{0}</b></li>",
				                    string.IsNullOrEmpty(ContentEncoding) ? "Not Compressed" : ContentEncoding + " compressed");

				if (LastException != null)
				{
					retVal.AppendFormat(CultureInfo.CurrentCulture,
					                    "<li>Reason to fail: <b>{0}</b></li>", LastException.Message);
				}
			}

			retVal.Append("</ul></div>");

			retVal.AppendFormat(CultureInfo.CurrentCulture, "<hr style='color:{0}; height: 0px;' />", "Gainsboro");

			return retVal.ToString();
		}
	}

	public class ProcessedFeedList : List<ProcessStatistics>
	{
		private DateTime? _ProcessTime;

		/// <summary>
		/// Date Time the processing started
		/// </summary>
		public DateTime? ProcessTime
		{
			get { return _ProcessTime; }
			set { _ProcessTime = value; }
		}

		public override string ToString()
		{
			StringBuilder retVal = new StringBuilder();

			if (Count > 0)
				ForEach(delegate(ProcessStatistics stat) { retVal.Append(stat); });
			else
				retVal.Append("There are no Process Statistics available!");

			return retVal.ToString();
		}

		public void ClearStatistics()
		{
			Clear();
			ProcessTime = null;
		}

		/// <summary>
		/// Gets a list of all downloads that have completed
		/// </summary>
		/// <returns></returns>
		public List<ProcessStatistics> GetFeedsWithNewContent()
		{
			return FindAll(delegate(ProcessStatistics ds) { return ds.NewEnclosures.Count > 0; });
		}
	}

	public class ProcessStatistics
	{
		public List<string> NewEnclosures = new List<string>();
		public Feed ProcessedFeed = null;


		///<summary>
		///Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
		///</summary>
		///
		///<returns>
		///A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
		///</returns>
		///<filterpriority>2</filterpriority>
		public override string ToString()
		{
			StringBuilder retVal = new StringBuilder();

			string color;

			if (NewEnclosures.Count > 0)
			{
				color = "DarkGreen";
			}
			else
			{
				color = "DodgerBlue";
			}

			retVal.AppendFormat(CultureInfo.CurrentCulture,
			                    "<div style='color:{1}'><b>{0}</b><br>&nbsp;&nbsp;New Podcasts: <b>{2}</b>, Download Max: <b>{3}</b>, Keep Max: <b>{4}</b>",
			                    ProcessedFeed.Name, color, NewEnclosures.Count, ProcessedFeed.MaxEnclosuresToOneStepDownload,
			                    ProcessedFeed.MaxEnclosures);

			if (NewEnclosures.Count > 0)
			{
				retVal.Append("<ul style='margin-top:5px; margin-bottom:5px'>");
				foreach (string s in NewEnclosures)
				{
					retVal.AppendFormat(CultureInfo.CurrentCulture, "<li>{0}</li>", s);
				}
				retVal.Append("</ul>");
			}

			retVal.Append("</div>");
			retVal.AppendFormat(CultureInfo.CurrentCulture, "<hr style='color:{0}; height: 0px;' />", "Gainsboro");

			return retVal.ToString();
		}
	}
}